package main

import (
	"cade/src/core"
	"cade/src/core/evtmgr"
	"cade/src/core/log"
	"cade/src/game/app"
	"cade/src/game/app/dbmgr"
	"cade/src/game/app/gamedata"
	"cade/src/game/app/gconst"
	"cade/src/game/app/modules/utils"
	"cade/src/game/handler"
	"cade/src/game/perfmon"
	"cade/src/shared/config"
	"flag"
	"math/rand"
	"os"
	"syscall"
	"time"
)

func main() {
	rand.Seed(time.Now().Unix())

	// parse command line
	arg_file := flag.String("config", "config.json", "config file")
	arg_server := flag.String("server", "game1", "server name")
	arg_log := flag.String("log", "", "log file")

	flag.Parse()

	// open log
	log.Open(*arg_log)

	// load config
	config.Parse(*arg_file, *arg_server)

	// signal
	quit := make(chan int)
	core.OnSignal(func(s os.Signal) {
		if s == syscall.SIGHUP {
			log.Warning("reloading ...")

			config.Parse(*arg_file, *arg_server)
			dbmgr.Open()
			evtmgr.Fire(gconst.Evt_ConfReload)
		} else {
			log.Warning("shutdown signal received ...")
			close(quit)
		}
	})

	start()
	<-quit
	stop()

	// close log
	log.Close()
}

func start() {

	// ============================================================================
	// INFRASTRUCTURE
	// ============================================================================

	// open db mgr
	dbmgr.Open()

	// load gamedata
	gamedata.Load()

	// init utils
	utils.Init(app.PlayerMgr)

	// ============================================================================
	// INIT WORLD
	// ============================================================================

	// ============================================================================
	// WORLD READY
	// ============================================================================

	evtmgr.Fire(gconst.Evt_WorldReady)

	// ============================================================================
	// PLAYER
	// ============================================================================

	app.PlayerMgr.Open()

	// ============================================================================
	// START WORLD
	// ============================================================================

	// ============================================================================
	// RUN
	// ============================================================================

	// start net mgr
	handler.Init()
	app.NetMgr.Start()

	// perfmon
	perfmon.Start()

	// fire
	evtmgr.Fire(gconst.Evt_ServerStart)

	// app started
	log.Notice("game started")
}

func stop() {

	// ============================================================================
	// STOP WORLD
	// ============================================================================

	// stop net mgr
	app.NetMgr.Stop()

	// ============================================================================
	// FINAL SAVE PLAYERS
	// ============================================================================

	app.PlayerMgr.Close()

	// ============================================================================
	// FINAL SAVE MODULES
	// ============================================================================

	// close db mgr
	dbmgr.Close()

	// fire
	evtmgr.Fire(gconst.Evt_ServerStop)

	// app stopped
	log.Notice("game stopped")
}
